﻿/*
 *author:keily ,department 2,wuda geo
 *date:2013-1-24
 *description:全文索引类
 */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Web;
using System.Xml;
using System.Text.RegularExpressions;

using Lucene.Net.Index;
using Lucene.Net.Documents;
using Lucene.Net.QueryParsers;
using Lucene.Net.Analysis;
using Lucene.Net.Search;
using Lucene.Net.Analysis.Standard;

using Lucene.Net.Analysis.PanGu;
using PanGu;
using PanGu.Dict;

namespace GeoWeb.FullTextSearchLib
{
    /// <summary>
    /// 全文索引类
    /// </summary>
    public class FullTextSearch
    {
        #region 配置、静态变量、索引器
        //配置文件路径
        private static string INITPANKUXML ;
        private static string INITCONFIGPATH ;
        private static string INDEXPATH ;
        private static string SUGGESTIONPATH ;
        
        
        private static List<QueryDataBaseCollection> _geoConfigCollection;
        /// <summary>
        /// 加载的全局的配置文件对象
        /// </summary>
        public static List<QueryDataBaseCollection> GeoConfigCollection
        {
            get { return _geoConfigCollection; }
        }
                
        
        private int _count;
        /// <summary>
        /// 用于存储检索出数据总数
        /// </summary>
        public int Count
        {
            get { return _count; }
            set { _count = value; }
        }
        private string _keyword;
        /// <summary>
        /// 搜索关键字
        /// </summary>
        public string KeyWord
        {
            get { return _keyword; }
            set { _keyword = value; }
        }
        
        private double _time;
        /// <summary>
        /// 搜索时间
        /// </summary>
        public double Time
        {
            get { return _time; }
            set { _time = value; }
        }


        #endregion
        /// <summary>
        /// 构造函数
        /// 初始化配置文件、字典文件、加载索引文件等操作
        /// </summary>
        public FullTextSearch()
        {
            //如果对象为空，则初始化对象
            if (GeoConfigCollection == null)
            {
                GeoWeb.Common.XMLHelper xmlHelpr= new GeoWeb.Common.XMLHelper();
                INITPANKUXML = xmlHelpr.GetXmlMapPath("PanGu");
                INITCONFIGPATH = xmlHelpr.GetXmlMapPath("QueryParamConfig");
                INDEXPATH = xmlHelpr.GetXmlMapPath("IndexDictionary");
                SUGGESTIONPATH = xmlHelpr.GetXmlMapPath("SuggestDict");

                //判断是否存在索引文件目录
                if (!System.IO.Directory.Exists(INDEXPATH))
                {
                    //不存在就创建索引目录
                    System.IO.Directory.CreateDirectory(INDEXPATH);
                    //创建索引文件
                }

                LoadQueryConfig(INITCONFIGPATH);
            }
        }
        /// <summary>
        /// 构造函数，手动加载索引文件
        /// </summary>
        /// <param name="_initConfigPath"></param>
        public FullTextSearch(string _initConfigPath)
        {
            //加载配置文件
            LoadQueryConfig(_initConfigPath);
        }

        #region 私有方法
        /// <summary>
        /// 加载配置文件
        /// </summary>
        /// <param name="xmlFilePath">配置文件路径</param>
        protected void LoadQueryConfig(string xmlFilePath)
        {
            //string xmlFilePath = @"QueryParamConfig.xml";
            //加载配置文件
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlFilePath);

            //读取配置文件
            string _name = "";
            string _table = "";
            string _typecode = "";
            string _title = "";
            string _querywhere = "";
            string _storgepath = "";

            string _subItem = "";
            bool _isIndex = false;

            //当前的索引文件路径
            string _curIndexPath = "";
            //使用xpath表达式选择文档中所有的Item子节点
            XmlNodeList itemNodeList = xmlDoc.SelectNodes("Root/Item");

            //申请List空间
            _geoConfigCollection = new List<QueryDataBaseCollection>(itemNodeList.Count);


            if (itemNodeList != null)
            {
                List<QueryFiled> QueryFiledList = null;
                foreach (XmlNode ItemtNode in itemNodeList)
                {
                    //通过Attributes获得属性名字为name的属性
                    _name = ItemtNode.Attributes["name"].Value;
                    _table = ItemtNode.Attributes["table"].Value;
                    _title = ItemtNode.Attributes["title"].Value;
                    _typecode = ItemtNode.Attributes["typecode"].Value;
                    _querywhere = ItemtNode.Attributes["querywhere"].Value;
                    _storgepath = ItemtNode.Attributes["storgepath"].Value;

                    //获得当前节点下的subitem子节点
                    XmlNodeList sunItemNodeList = ItemtNode.SelectNodes("subitem");


                    QueryFiledList = new List<QueryFiled>(sunItemNodeList.Count);


                    if (sunItemNodeList != null)
                    {
                        foreach (XmlNode subItemNode in sunItemNodeList)
                        {
                            _subItem = subItemNode.Attributes["name"].Value;
                            _isIndex = subItemNode.Attributes["IsIndex"].Value.ToString() == "true" ? true : false;

                            QueryFiled _queryFiled = new QueryFiled(_isIndex, _subItem);
                            QueryFiledList.Add(_queryFiled);
                        }
                    }

                    _curIndexPath = System.IO.Path.Combine(INDEXPATH, _table);

                    QueryDataBaseCollection _collection = new QueryDataBaseCollection(
                    _name,
                    _table,
                    QueryFiledList,
                    _curIndexPath,
                    _querywhere,
                    _typecode);


                    _geoConfigCollection.Add(_collection);

                }

            }

        }
        /// <summary>
        /// 得到数据结果集
        /// </summary>
        /// <returns></returns>
        protected DataTable GetSqlDS(string sql)
        {
            DbUtity utity = new DbUtity();
            return utity.Db.FromSql(sql, null).ToTable() as DataTable;
            //return syaisLibary.DBUtility.DbHelperSQL.Query(sql).Tables[0];
        }

        /// <summary>
        /// 添加索引域
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="dataTable"></param>
        protected void AddDocument(IndexWriter writer, DataTable dataTable, QueryDataBaseCollection _collection)
        {
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                Document doc = new Document();

                foreach (QueryFiled filed in _collection.QueryFiledList)
                {
                    doc.Add(new Field(
                        filed.FiledName,
                        dataTable.Rows[i][filed.FiledName].ToString(),
                        Field.Store.YES,
                        filed.IsIndex == true ? Field.Index.ANALYZED : Field.Index.NOT_ANALYZED
                        ));
                }

                writer.AddDocument(doc);
            }

        }
        /// <summary>
        /// 创建索引文件
        /// </summary>
        protected void CreateAnalyzerIndex(QueryDataBaseCollection _collection)
        {

            string _INDEX_FILEPATH = _collection.StorgeDictionary;

            //判断是否存在索引文件目录
            if (!System.IO.Directory.Exists(_INDEX_FILEPATH))
            {
                //不存在就创建索引目录
                System.IO.Directory.CreateDirectory(_INDEX_FILEPATH);
                //创建索引文件
            }

            //修改文件自读属性
            if (System.IO.FileAttributes.ReadOnly == System.IO.File.GetAttributes(_INDEX_FILEPATH))
            {
                System.IO.File.SetAttributes(_INDEX_FILEPATH, System.IO.FileAttributes.Normal);
            }

            PanGu.Segment.Init(INITPANKUXML);

            AnalyzerModule CusGeoAnalyzer = new AnalyzerModule();
            Analyzer analyzer = CusGeoAnalyzer.CreateAnalyzer();

            Lucene.Net.Store.Directory _luceneIndexDirectory = Lucene.Net.Store.FSDirectory.Open(new System.IO.DirectoryInfo(_INDEX_FILEPATH));
            IndexWriter writer = new IndexWriter(_luceneIndexDirectory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);

            //查询数据库，建立索引文件
            string strSql = _collection.GetSQLExpression();
            DataTable dataTable = GetSqlDS(strSql);
            AddDocument(writer, dataTable, _collection);
            writer.Optimize();
            writer.Close();
        }
        /// <summary>
        /// 创建pangu分词的索引文件
        /// </summary>
        [Obsolete("Use CreateAnalyzerIndex(QueryDataBaseCollection) instead.此方法会使全局配置失效")]
        protected void CreatePanGuIndex(QueryDataBaseCollection _collection)
        {

            string _INDEX_FILEPATH = _collection.StorgeDictionary;

            //判断是否存在索引文件目录
            if (!System.IO.Directory.Exists(_INDEX_FILEPATH))
            {
                //不存在就创建索引目录
                System.IO.Directory.CreateDirectory(_INDEX_FILEPATH);
                //创建索引文件
            }

            PanGu.Segment.Init(INITPANKUXML);
            PanGuAnalyzer analyzer = new PanGuAnalyzer();
            Lucene.Net.Store.Directory _luceneIndexDirectory = Lucene.Net.Store.FSDirectory.Open(new System.IO.DirectoryInfo(_INDEX_FILEPATH));
            IndexWriter writer = new IndexWriter(_luceneIndexDirectory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);

            //查询数据库，建立索引文件
            string strSql = _collection.GetSQLExpression();
            DataTable dataTable = GetSqlDS(strSql);
            AddDocument(writer, dataTable, _collection);
            writer.Optimize();
            writer.Close();
        }
        /// <summary>
        /// lucene自带的单字分词 创建索引文件
        /// </summary>
        /// <param name="_collection">配置文件</param>
        [Obsolete("Use CreateAnalyzerIndex(QueryDataBaseCollection) instead.此方法会使全局配置失效")]
        protected void CreateStandardIndex(QueryDataBaseCollection _collection)
        {
            string _INDEX_FILEPATH = _collection.StorgeDictionary;

            //判断是否存在索引文件目录
            if (!System.IO.Directory.Exists(_INDEX_FILEPATH))
            {
                //不存在就创建索引目录
                System.IO.Directory.CreateDirectory(_INDEX_FILEPATH);
                //创建索引文件
            }

            Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29);

            Lucene.Net.Store.Directory _luceneIndexDirectory = Lucene.Net.Store.FSDirectory.Open(new System.IO.DirectoryInfo(_INDEX_FILEPATH));
            IndexWriter writer = new IndexWriter(_luceneIndexDirectory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
            //IndexWriter writer = new IndexWriter(_INDEX_FILEPATH,  analyzer,  true,  IndexWriter.MaxFieldLength.LIMITED);

            //查询数据库，建立索引文件
            string strSql = _collection.GetSQLExpression();
            DataTable dataTable = GetSqlDS(strSql);
            AddDocument(writer, dataTable, _collection);
            writer.Optimize();
            writer.Close();
        }

        /// <summary>
        /// 对搜索的词进行分词
        /// </summary>
        /// <param name="keyWords">要收索的词</param>
        /// <param name="ktTokenizer">分词对象</param>
        /// <returns>分词后的结果</returns>
        protected string GetKeyWordSplitBySpace(string keyWords, PanGuTokenizer ktTokenizer)
        {
            StringBuilder builder = new StringBuilder();
            ICollection<WordInfo> words = ktTokenizer.SegmentToWordInfos(keyWords);
            foreach (WordInfo word in words)
            {
                if (word == null)
                {
                    continue;
                }
                KeyWord = KeyWord + word + ",";
                builder.AppendFormat("{0}^{1}", word.Word, (int)Math.Pow(3, word.Rank));
            }

            KeyWord = KeyWord.Substring(0, KeyWord.Length - 1);
            return builder.ToString().Trim();
        }

        #endregion

        #region 公有方法
        /// <summary>
        /// 创建索引文件
        /// </summary>
        /// <returns></returns>
        public bool CreateIndex()
        {
            //如果全局配置文件为空，返回失败
            if (GeoConfigCollection == null)
                return false;

            foreach (QueryDataBaseCollection q in _geoConfigCollection)
            {
                CreateAnalyzerIndex(q);
                //CreatePanGuIndex(q);
            }

            return true;
        }
        
        /// <summary>
        /// 检索详细信息
        /// </summary>
        /// <param name="keyWord">检索关键字</param>
        /// <param name="pageNumber">当前第几条</param>
        /// <param name="pageSize">每页显示的条数</param>
        /// <returns></returns>
        public string Search(string keyWord, int pageNumber, int pageSize )
        {
            //init panku.xml
            Lucene.Net.Analysis.PanGu.PanGuTokenizer.InitPanGuSegment(INITPANKUXML);

            //关键词
            string word = GetKeyWordSplitBySpace(keyWord, new Lucene.Net.Analysis.PanGu.PanGuTokenizer());
            

            //实例化索引
            List<IndexReader> IndexReaderArray = new List<IndexReader>(_geoConfigCollection.Count);
            foreach (QueryDataBaseCollection _collection in _geoConfigCollection)
            {

                Lucene.Net.Store.Directory _luceneIndexDirectory = Lucene.Net.Store.FSDirectory.Open(new System.IO.DirectoryInfo( _collection.StorgeDictionary ));

                IndexReaderArray.Add(IndexReader.Open(_luceneIndexDirectory, true));    
            }

            MultiReader reader = new MultiReader(IndexReaderArray.ToArray());


            IndexSearcher search = new IndexSearcher(reader);
            StringBuilder builder = new StringBuilder();
            Analyzer analyzer = (new AnalyzerModule()).CreateAnalyzer();


            //多字段搜索字段
            List<string> _indexWordList = new List<string>();
            foreach (QueryDataBaseCollection _collection in _geoConfigCollection)
            {
                foreach (QueryFiled _filed in _collection.QueryFiledList)
                {
                    //将标示索引的数据加入到索引词中 
                    if (_filed.IsIndex)
                    {
                        _indexWordList.Add(_filed.FiledName);
                    }
                }
            }

            MultiFieldQueryParser parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29,
                _indexWordList.ToArray(), analyzer);


            //分词
            Query query = parser.Parse(word);
            Hits hits = search.Search(query);


            //显示数据
            Count = hits.Length();
            int num = 0;//记录每页最后一条
            if (Count < pageNumber + pageSize)
            {
                num = Count;
            }
            else
            {
                num = pageSize + pageNumber;
            }
            DateTime begin = DateTime.Now;
            for (int i = pageNumber; i < num; i++)
            {
                Document doc = hits.Doc(i);

                //创建HTMLFormatter,参数为高亮搜索词的HTML代码
                PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("<font color='red'>", "</font>");
                //创建高亮，输入HTML代码和 盘古对象Semgent
                PanGu.HighLight.Highlighter highter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new Segment());
                //设置每个摘要字段的字符数
                highter.FragmentSize = 200;
                builder.Append("<div style='background-color: bisque;'>");

                string o = "";
                string[] _arr = new string[2];
                string strPrint = "";
                string key = "";
                string values = "";
                string _stemp = "";

                foreach (Field _curField in doc.GetFields())
                {
                    key = _curField.Name();
                    values = _curField.StringValue();
                    _stemp = highter.GetBestFragment(keyWord, values);
                    if (_stemp == "")
                    {
                        _stemp = values;
                    }
                    _stemp = key + ":" + _stemp + "</br>";
                    strPrint += _stemp;
                }


                builder.Append(strPrint + "</br>");
                builder.Append("</div></br>");

            }
            DateTime end = DateTime.Now;
            double ts = (end - begin).TotalMilliseconds;
            Time = ts / 1000.000;
            search.Close();//关闭检索器
            return builder.ToString();
        }

        /// <summary>
        /// 后去检索信息得到的数据集
        /// </summary>
        /// <param name="keyWord">检索关键字</param>
        /// <returns></returns>
        [Obsolete("Use GetCustomSearchData(string) instead.此方法会使全局配置失效")]
        public IDictionary<string, string> GetPanGuSearchData(string keyWord )
        {
            //init panku.xml
            Lucene.Net.Analysis.PanGu.PanGuTokenizer.InitPanGuSegment(INITPANKUXML);
            //关键词
            string word = GetKeyWordSplitBySpace(keyWord, new Lucene.Net.Analysis.PanGu.PanGuTokenizer());
            
            //实例化索引
            List<IndexReader> IndexReaderArray = new List<IndexReader>(_geoConfigCollection.Count);
            foreach (QueryDataBaseCollection _collection in _geoConfigCollection)
            {
                //
                Lucene.Net.Store.Directory _luceneIndexDirectory = Lucene.Net.Store.FSDirectory.Open(new System.IO.DirectoryInfo(_collection.StorgeDictionary));
                IndexReaderArray.Add(IndexReader.Open(_luceneIndexDirectory));
            }

            MultiReader reader = new MultiReader(IndexReaderArray.ToArray());


            IndexSearcher search = new IndexSearcher(reader);
            StringBuilder builder = new StringBuilder();
            PanGuAnalyzer analyzer = new PanGuAnalyzer(true);
            

            //多字段搜索字段
            List<string> _indexWordList = new List<string>();
            foreach (QueryDataBaseCollection _collection in _geoConfigCollection)
            {
                foreach (QueryFiled _filed in _collection.QueryFiledList)
                    //将标示索引的数据加入到索引词中 
                    if (_filed.IsIndex)
                    {
                        _indexWordList.Add(_filed.FiledName);
                    }
            }

            MultiFieldQueryParser parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29,
                _indexWordList.ToArray(), analyzer);


            //分词
            Query query = parser.Parse(word);
            Hits hits = search.Search(query);



            //显示数据
            Count = hits.Length();
            //返回的数据字典
            IDictionary<string, string> retDict = new Dictionary<string, string>(Count);

            //申明正则匹配数据
            string patID = "<序号:(.*?)>";
            string patCode = "<typecode:(.*?)>";

            Regex rID = new Regex(patID, RegexOptions.IgnoreCase);
            Regex rCode = new Regex(patCode, RegexOptions.IgnoreCase);

            for (int i = 0; i < Count; i++)
            {
                Document doc = hits.Doc(i);

                Match _mID = rID.Match(doc.ToString());
                Match _mCode = rCode.Match(doc.ToString());

                //如果匹配成功
                if (_mID.Success)
                {
                    Group g = _mID.Groups[1];
                    if (g.Value.ToString() != "")
                    {
                        try
                        {
                            retDict.Add(g.Value.ToString(),
                                _mCode.Success == true ? _mCode.Groups[1].Value.ToString() : ""
                                );
                        }
                        //如果重复，覆盖以前的
                        catch (ArgumentException)
                        {
                            retDict[g.Value.ToString()] = _mCode.Success == true ? _mCode.Groups[1].Value.ToString() : "";

                        }

                    }
                }
            }


            return retDict;
        }
        /// <summary>
        /// lucene自带的分词查询
        /// </summary>
        /// <param name="keyWord">关键词</param>
        /// <returns></returns>
        [Obsolete("Use GetCustomSearchData(string) instead.此方法会使全局配置失效")]
        public IDictionary<string, string> GetStandardSearchData(string keyWord )
        {
            //init panku.xml
            Lucene.Net.Analysis.PanGu.PanGuTokenizer.InitPanGuSegment(INITPANKUXML);
            //关键词
            string word = GetKeyWordSplitBySpace(keyWord, new Lucene.Net.Analysis.PanGu.PanGuTokenizer());

            //实例化索引
            List<IndexReader> IndexReaderArray = new List<IndexReader>(_geoConfigCollection.Count);
            foreach (QueryDataBaseCollection _collection in _geoConfigCollection)
            {
                Lucene.Net.Store.Directory _luceneIndexDirectory = Lucene.Net.Store.FSDirectory.Open(new System.IO.DirectoryInfo(_collection.StorgeDictionary));
                IndexReaderArray.Add(IndexReader.Open(_luceneIndexDirectory));
            }

            MultiReader reader = new MultiReader(IndexReaderArray.ToArray());


            IndexSearcher search = new IndexSearcher(reader);
            StringBuilder builder = new StringBuilder();
            Analyzer analyzer = new StandardAnalyzer(true);

            //多字段搜索字段
            List<string> _indexWordList = new List<string>();
            foreach (QueryDataBaseCollection _collection in _geoConfigCollection)
            {
                foreach (QueryFiled _filed in _collection.QueryFiledList)
                    //将标示索引的数据加入到索引词中 
                    if (_filed.IsIndex)
                    {
                        _indexWordList.Add(_filed.FiledName);
                    }
            }

            MultiFieldQueryParser parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29,
                _indexWordList.ToArray(), analyzer);


            //分词
            Query query = parser.Parse(word);
            Hits hits = search.Search(query);



            //显示数据
            Count = hits.Length();
            //返回的数据字典
            IDictionary<string, string> retDict = new Dictionary<string, string>(Count);

            //申明正则匹配数据
            string patID = "<序号:(.*?)>";
            string patCode = "<typecode:(.*?)>";

            Regex rID = new Regex(patID, RegexOptions.IgnoreCase);
            Regex rCode = new Regex(patCode, RegexOptions.IgnoreCase);

            for (int i = 0; i < Count; i++)
            {
                Document doc = hits.Doc(i);

                Match _mID = rID.Match(doc.ToString());
                Match _mCode = rCode.Match(doc.ToString());

                //如果匹配成功
                if (_mID.Success)
                {
                    Group g = _mID.Groups[1];
                    if (g.Value.ToString() != "")
                    {
                        try
                        {
                            retDict.Add(g.Value.ToString(),
                                _mCode.Success == true ? _mCode.Groups[1].Value.ToString() : ""
                                );
                        }
                        //如果重复，覆盖以前的
                        catch (ArgumentException)
                        {
                            retDict[g.Value.ToString()] = _mCode.Success == true ? _mCode.Groups[1].Value.ToString() : "";

                        }

                    }
                }
            }


            return retDict;
        }
        /// <summary>
        /// 自定义查询集合
        /// </summary>
        /// <param name="keyWord">关键词</param>
        /// <returns></returns>
        public CustomQueryCollection<QueryEntity> GetCustomSearchData(string keyWord )
        {
            //返回数据集
            CustomQueryCollection<QueryEntity> CQColleection =null;

            string curID = "序号";
            string curCode = "typecode";
            string curDept = "行政区划";

            Field _id = null;
            Field _code = null;
            Field _dept = null;

            //init panku.xml
            Lucene.Net.Analysis.PanGu.PanGuTokenizer.InitPanGuSegment(INITPANKUXML);

            //关键词
            string word = GetKeyWordSplitBySpace(keyWord, new Lucene.Net.Analysis.PanGu.PanGuTokenizer());
            //string word = keyWord;

            //实例化索引
            List<IndexReader> IndexReaderArray = new List<IndexReader>(_geoConfigCollection.Count);
            foreach (QueryDataBaseCollection _collection in _geoConfigCollection)
            {
                Lucene.Net.Store.Directory _luceneIndexDirectory = Lucene.Net.Store.FSDirectory.Open(new System.IO.DirectoryInfo(_collection.StorgeDictionary));
                IndexReaderArray.Add(IndexReader.Open(_luceneIndexDirectory,true));                
            }

            MultiReader reader = new MultiReader(IndexReaderArray.ToArray());

            
            IndexSearcher search = new IndexSearcher(reader);
            StringBuilder builder = new StringBuilder();
            //PanGuAnalyzer analyzer = new PanGuAnalyzer(true);
            Analyzer analyzer = (new AnalyzerModule()).CreateAnalyzer();

            //多字段搜索字段
            List<string> _indexWordList = new List<string>();
            foreach (QueryDataBaseCollection _collection in _geoConfigCollection)
            {
                foreach (QueryFiled _filed in _collection.QueryFiledList)
                    //将标示索引的数据加入到索引词中 
                    if (_filed.IsIndex)
                    {
                        _indexWordList.Add(_filed.FiledName);
                    }
            }

            MultiFieldQueryParser parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29,
                _indexWordList.ToArray(), analyzer);


            //如果搜索词未空，默认返回所有数据
            if (keyWord == null || keyWord.Equals(string.Empty))
            {
                Count = reader.NumDocs();

                CQColleection = new CustomQueryCollection<QueryEntity>(Count);

                int _curIndex =0;
                while (_curIndex < Count)
                {

                    Document doc = reader.Document(_curIndex);

                    _id = doc.GetField(curID);
                    _code = doc.GetField(curCode);
                    _dept = doc.GetField(curDept);

                    CQColleection.Add(new QueryEntity(
                        _id == null ? "" : _id.StringValue(),
                        _code == null ? "" : _code.StringValue(),
                        _dept == null ? "" : _dept.StringValue()
                        ));

                    _curIndex++;
                }
                
                //return
                return CQColleection;
            }



            //分词
            Query query = parser.Parse(word);
            Hits hits = search.Search(query);



            //显示数据
            Count = hits.Length();

            //返回的数据字典
            CQColleection = new CustomQueryCollection<QueryEntity>(Count);


            for (int i = 0; i < Count; i++)
            {
                Document doc = hits.Doc(i);

                _id = doc.GetField(curID);
                _code = doc.GetField(curCode);
                _dept = doc.GetField(curDept);

                CQColleection.Add(new QueryEntity(
                    _id == null ? "" : _id.StringValue(),
                    _code == null ? "" : _code.StringValue(),
                    _dept == null ? "" : _dept.StringValue()
                    ));
            }


            return CQColleection;
        }
               
        /// <summary>
        /// 智能提示
        /// </summary>
        /// <param name="words">关键词</param>
        /// <param name="showTopNum">显示前多少条数据</param>
        /// <returns></returns>
        public static string SearchSuggestion(string words,int showTopNum)
        {
            if (words.Trim().Equals(""))
                return "";

            if (SUGGESTIONPATH==null) SUGGESTIONPATH = new GeoWeb.Common.XMLHelper().GetXmlMapPath("SuggestDict");
            string strFileName = SUGGESTIONPATH;

            WordDictionary Dict = new WordDictionary();
            Dict.Load(strFileName);
            List<SearchWordResult> resultLists = Dict.Search(words);
            StringBuilder strb=new StringBuilder();
            foreach (SearchWordResult _sWords in resultLists)
            {
                if (showTopNum-- <= 0)
                    break;

                if (_sWords.ToString().Length>1 )
                    strb.Append(_sWords.ToString() + "&");
                
            }

            if (strb.ToString().Length==0)
                return "";

            return strb.ToString().Substring(0,strb.Length-1);
        }

        #endregion 
    }
}
